﻿using Microsoft.SemanticKernel;
using System.ComponentModel;
using CodeAgent.Host.Agents;
using CodeAgent.Host.Context;
using CodeAgent.Host.Docker;

public class DockerSkill
{
    private readonly DockerManager _dockerManager;

    public DockerSkill()
    {
        _dockerManager = new DockerManager();
    }

    [KernelFunction, Description("Deploy and run code in a container")]
    public async Task<string> DeployAndRunCode(
        [Description("The name for the new container")]
        string containerName,
        [Description("The image to use")] string imageName,
        [Description("The host directory path containing the code")]
        string hostCodePath,
        [Description("The container directory to mount code")]
        string containerCodePath,
        [Description("The command to run")] string[] command,
        [Description("The Ports in containers, internal ports:external ports ")]
        string port,
        [Description("The working directory in container")]
        string workingDir,
        [Description("The image tag")] string tag = "latest")
    {
        var id = Guid.NewGuid().ToString();

        try
        {
            if (AgentContext.Current?.NotifyAction != null)
                await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
                {
                    Id = id,
                    type = "info",
                    message = $"部署容器 {containerName} ，镜像 {imageName}:{tag}",
                    code = 200,
                    error = null
                });

            // First pull the image if needed
            await _dockerManager.PullImageAsync($"{imageName}", tag);

            // Create and start container with volume mapping
            string containerId = await _dockerManager.CreateAndStartContainerAsync(
                containerName,
                $"{imageName}:{tag}",
                hostCodePath,
                containerCodePath,
                command,
                workingDir, port,id);


            if (AgentContext.Current?.NotifyAction != null)
                await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
                {
                    Id = id,
                    type = "info",
                    message = $"容器 {containerName} 部署成功，ID {containerId}",
                    code = 200,
                    error = null
                });

            return $"Successfully deployed container {containerName} with ID {containerId}";
        }
        catch (Exception ex)
        {
            if (AgentContext.Current?.NotifyAction != null)
                await AgentContext.Current!.NotifyAction!.Invoke(new AgentConsoleProtocol
                {
                    Id = id,
                    type = "info",
                    message = $"部署和运行代码失败: {ex.Message}",
                    code = 200,
                    error = null
                });
            return $"Failed to deploy and run code: {ex.Message}";
        }
    }

    [KernelFunction, Description("Pull a Docker image from registry")]
    public async Task<string> PullImage(
        [Description("The name of the Docker image to pull")]
        string imageName,
        [Description("The tag of the Docker image")]
        string tag = "latest")
    {
        try
        {
            await _dockerManager.PullImageAsync(imageName, tag,
                progress: message => { Console.WriteLine($"Pull progress: {message.Status} {message.Progress}"); });
            return $"Successfully pulled image {imageName}:{tag}";
        }
        catch (Exception ex)
        {
            return $"Failed to pull image: {ex.Message}";
        }
    }

    [KernelFunction, Description("Create and start a new Docker container")]
    public async Task<string> CreateAndStartContainer(
        [Description("The name for the new container")]
        string containerName,
        [Description("The image to use for the container")]
        string imageName)
    {
        try
        {
            string containerId = await _dockerManager.CreateAndStartContainerAsync(containerName, imageName);
            return $"Successfully created and started container {containerName} with ID {containerId}";
        }
        catch (Exception ex)
        {
            return $"Failed to create and start container: {ex.Message}";
        }
    }

    [KernelFunction, Description("Stop and remove a Docker container")]
    public async Task<string> StopAndRemoveContainer(
        [Description("The ID of the container to stop and remove")]
        string containerId)
    {
        try
        {
            await _dockerManager.StopAndRemoveContainerAsync(containerId);
            return $"Successfully stopped and removed container {containerId}";
        }
        catch (Exception ex)
        {
            return $"Failed to stop and remove container: {ex.Message}";
        }
    }

    [KernelFunction, Description("Deploy a container from an image with automatic cleanup")]
    public async Task<string> DeployContainer(
        [Description("The name for the new container")]
        string containerName,
        [Description("The image to deploy")] string imageName,
        [Description("The image tag to deploy")]
        string tag = "latest")
    {
        try
        {
            // First pull the image
            await _dockerManager.PullImageAsync($"{imageName}", tag);

            // Then create and start the container
            string containerId = await _dockerManager.CreateAndStartContainerAsync(containerName, $"{imageName}:{tag}");

            return $"Successfully deployed container {containerName} with ID {containerId}";
        }
        catch (Exception ex)
        {
            return $"Failed to deploy container: {ex.Message}";
        }
    }
}